#ifndef _MULTICAST_H_
#define _MULTICAST_H_

#if defined(_WIN32) || defined(_WIN64)
#include <winsock2.h>   //链接时需要添加 -lwsock32
#include <windows.h>
#include <ws2tcpip.h>
#else   /* defined(_WIN32) || defined(_WIN64) */
#include <netinet/in.h>
#include <arpa/inet.h>
#endif  /* defined(_WIN32) || defined(_WIN64) */
#include <stdint.h>


struct multicast_handle
{
    int sockfd;     //socket
    struct sockaddr_in multicast_addr; //multicast info
    struct sockaddr_in remote_addr; //remote info
    struct ip_mreq my_mreq;     //multicast group
};

/**
 * @brief join a multicast group 
 * 
 * @param mch handle
 * @param multicast_ip join the group by ip. each ip is one group. the range of ip is 224.0.0.1 – 239.255.255.255 
 * @param local_ip input this device ip, or NULL for INADDR_ANY
 * @param port port
 * @return int return the socket file descriptor, see socket(). -1 is fail
 */
int multicast_join(struct multicast_handle *mch, char *multicast_ip, char *local_ip, uint16_t port);

/**
 * @brief send data to multicast group
 * 
 * @param mch handle
 * @param buff data that need to be send
 * @param buflen data length
 * @return int the data length that send to, see sendto(). 
 * @note you can use sendto() to instead, the socket was return by multicast_join()
 */
int multicast_send(struct multicast_handle *mch, char* buff, int buflen);

/**
 * @brief receive data form multicast group
 * 
 * @param mch handle
 * @param buff output received data
 * @param buflen the max buff length
 * @return int the received data length , see recvfrom().
 * @note the function will keep waiting until receive data, or use recvfrom() instead this function
 */
int multicast_recv(struct multicast_handle *mch, char* buff, int buflen);

/**
 * @brief exit group and close socket
 * 
 * @param mch handle
 * @return int 0 success, -1 fail
 */
int multicast_close(struct multicast_handle *mch);

#endif

